require "heros"
require 'table'
--
-- 1: no equip
-- 1.5: equip white
-- 1.7: equip green
-- 2.0: equip blue
-- 2.5: equip purple
--

--
--	create hero instance base on hero class
--	lvl: specific lvl of hero instance that to be created
--	equip: hero main equip certain equipment
--
function create_hero_instance(heroc, lvl, equip)
	inst =
	{
		lvl = 1, hp = 1, mp = 1,
		vit = 0, str = 0, agi=0, int=0,
		tohit=0, tododge=0,
		c=0, t=0,
		ap=0, dp=0,
		damage =
		{
			base = 1,
			spec = 1,
		}
	}

	inst.lvl = lvl
	inst.cls = heroc.cls
	inst.name = heroc.name

	if not equip then equip = 1 end

	inst.vit = heroc.vit.b + heroc.vit.a * lvl * equip
	inst.str = heroc.str.b + heroc.str.a * lvl * equip
	inst.agi = heroc.agi.b + heroc.agi.a * lvl * equip
	inst.int = heroc.int.b + heroc.int.a * lvl * equip

	inst.hp_rate = 10 
	inst.mp_rate = 10 
	reset_hero_instance(inst)

	--show_hero_instance(inst)

	inst.tohit	= heroc.tohit.b	+ heroc.tohit.a * inst.agi
	inst.tododge	= heroc.tododge.b	+ heroc.tododge.a * inst.agi

	inst.c	= heroc.c.b + heroc.c.a * lvl * equip
	inst.t	= heroc.t.b + heroc.t.a * lvl * equip

	--	str heros use str as main attributes
	--	agi heros use agi as main attributes
	--	int heros use int as main attributes
	local matt = 0
	if (heroc.cls==1) then
		matt = inst.str
	elseif (heroc.cls==2) then
		matt = inst.agi
	else
		matt = inst.int
	end

	--	ap is base on main attributes
	--	dp is base on str
	inst.ap	= heroc.ap.b + heroc.ap.a * matt
	inst.dp = heroc.dp.b + heroc.dp.a * inst.str

	inst.damage = {}
	for k,v in pairs(heroc.skills) do
		local skill = skills[v.id]
		inst.damage[k] = 
		{ 
			d = skill.x + skill.y * lvl * equip, 
			w = v.w,
			id = v.id,
		}
	end
	inst.critical = heroc.critical

	return inst
end

--
--	create monster instance base on hero template
--	lvl: overide the lvl info in monster data
--	equip: overide the equip info in monster data
--
function create_monster_instance(m, lvl, equip)
	--
	--	get the hero template which the monster rely on
	--	it can't be null, or the monster can not be instanced
	local heroc = heros[m.hero]
	if not heroc then
		print("Null base hero for monster")
		return
	end

	--
	--	a default role instance
	inst =
	{
		lvl = 1, hp = 1, mp = 1,
		vit = 0, str = 0, agi=0, int=0,
		tohit=0, tododge=0,
		c=0, t=0,
		ap=0, dp=0,
		damage =
		{
			base = 1,
			spec = 1,
		}
	}

	lvl = lvl or m.lvl
	inst.lvl = lvl
	inst.cls = heroc.cls
	inst.name = m.name or heroc.name
	equip = equip or m.equip

	inst.vit = heroc.vit.b + heroc.vit.a * lvl * equip
	inst.str = heroc.str.b + heroc.str.a * lvl * equip
	inst.agi = heroc.agi.b + heroc.agi.a * lvl * equip
	inst.int = heroc.int.b + heroc.int.a * lvl * equip

	--
	--	standard ht rate and mp rate is 10
	--	but monster will have a modifier which can make the monster weaker or stronger
	inst.hp_rate = 10 * m.hp_rate
	inst.mp_rate = 10 * m.mp_rate
	reset_hero_instance(inst)

	--show_hero_instance(inst)

	inst.tohit	= heroc.tohit.b		+ heroc.tohit.a * inst.agi
	inst.tododge	= heroc.tododge.b	+ heroc.tododge.a * inst.agi

	inst.c	= heroc.c.b + heroc.c.a * lvl * equip
	inst.t	= heroc.t.b + heroc.t.a * lvl * equip

	--	str heros use str as main attributes
	--	agi heros use agi as main attributes
	--	int heros use int as main attributes
	local matt = 0
	if (heroc.cls==1) then
		matt = inst.str
	elseif (heroc.cls==2) then
		matt = inst.agi
	else
		matt = inst.int
	end

	--	ap is base on main attributes
	--	dp is base on str
	inst.ap	= heroc.ap.b + heroc.ap.a * matt
	inst.dp = heroc.dp.b + heroc.dp.a * inst.str

	--
	--	monster may not inherit all skill from its template hero
	--	it will select skills base on m.skill selector
	inst.damage = {}
	local ws = 0
	for k,v in pairs(heroc.skills) do
		if m.skill:find(tostring(k)) then
			local skill = skills[v.id]
			inst.damage[k] = 
			{ 
				d = skill.x + skill.y * lvl * equip, 
				w = v.w,
				id = v.id,
			}
			ws = ws + v.w
		end
	end

	if ws<100 and ws>0 then
		for k,v in pairs(inst.damage) do
			v.w = v.w * 100 / ws
		end
	end
	inst.critical = heroc.critical

	return inst
end

--
--	reset hero mp and hp base on its vit and int
--
function reset_hero_instance(heroi)
	heroi.hp = heroi.vit * heroi.hp_rate
	heroi.mp = heroi.int * heroi.mp_rate
end

function show_hero_instance(heroi)
	print("******************************************************************")
	print("**lvl:			", heroi.lvl, heroi.hp.."/"..heroi.mp, heros_name[heroi.cls])
	print("**vit/str/agi/int:	", heroi.vit, heroi.str, heroi.agi, heroi.int)
	print("**tohit/tododge:	", heroi.tohit, heroi.tododge)
	print("**critical/toughness:	", heroi.c, heroi.t)
	print("**ap/dp:		", heroi.ap, heroi.dp)
	print("**skill cnt:		", table.getn(heroi.damage))
	print("******************************************************************")
end
